"""
主题: 实现自定义容器
问题: 你想实现一个自定义的类来模拟内置的容器类功能，比如列表和字典。但是你不确定到底要实现哪些方法。
提示 : 
"""

import collections.abc as collections
import bisect

class SortedItems(collections.Sequence):
    def __init__(self, initial=None):
        self._items = sorted(initial) if initial is not None else []

    # Required sequence methods
    def __getitem__(self, index):
        return self._items[index]

    def __len__(self):
        return len(self._items)

    # Method for adding an item in the right location
    def add(self, item):
        bisect.insort(self._items, item)

class Items(collections.MutableSequence):
    def __init__(self, initial=None):
        self._items = list(initial) if initial is not None else []

    # Required sequence methods
    def __getitem__(self, index):
        print('Getting:', index)
        return self._items[index]

    def __setitem__(self, index, value):
        print('Setting:', index, value)
        self._items[index] = value

    def __delitem__(self, index):
        print('Deleting:', index)
        del self._items[index]

    def insert(self, index, value):
        print('Inserting:', index, value)
        self._items.insert(index, value)

    def __len__(self):
        print('Len')
        return len(self._items)

def recipe1():
    items = SortedItems([5, 1, 3])
    print(f"{list(items) = }")
    print(f"{items[0], items[-1] = }")
    items.add(2)
    print(f"{list(items) = }")

    print(f"{isinstance(items, collections.Iterable) = }")
    print(f"{isinstance(items, collections.Sequence) = }")
    print(f"{isinstance(items, collections.Container) = }")
    print(f"{isinstance(items, collections.Sized) = }")
    print(f"{isinstance(items, collections.Mapping) = }")
    
    
def recipe2():
    a = Items([1, 2, 3])
    print(f"{len(a) = }")

    print(f"{a.append(4) = }")
    print(f"{a.append(2) = }")
    print(f"{a.count(2) = }")
    print(f"{a.remove(3) = }")

def main():
    print('recipe1'.center(20, '*'))
    recipe1()
    print('recipe2'.center(20, '*'))
    recipe2()

if __name__ == '__main__':
    main()           